package com.iotp.controller.admin.authority;

import com.alibaba.fastjson.JSONObject;
import com.iotp.controller.admin.base.BaseController;
import com.iotp.entity.authority.Authority;
import com.iotp.entity.base.DataMessage;
import com.iotp.entity.base.KKpager;
import com.iotp.service.authority.AuthorityService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iotp.utils.common.WyConstant;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import java.io.*;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;


/**
 * 系统权限管理控制器
 * @author Assassin
 */
@Controller
@RequestMapping("/sys/authority")
public class AuthorityController extends BaseController {
	
	@Autowired
	private AuthorityService authorityService;// 系统权限业务接口
	
	/**
	 * 进入系统权限列表页面
	 * @return sys/authority/list_authority
	 */
	@GetMapping("/list")
	public String gotoListPage() {
		return "admin/sys/authority/list_authority";
	}
	
	/**
	 * 进入系统权限添加页面
	 * @return sys/authority/add_root_authority
	 */
	@GetMapping("/toAddRoot")
	public String gotoAddRootPage() {
		return "admin/sys/authority/add_root_authority";
	}
	
	/**
	 * 进入系统权限添加页面
	 * @return sys/authority/add_sub_authority
	 */
	@GetMapping("/toAddSub")
	public String gotoAddSubPage(String authorityPid) {
		// 后台数据验证
		if(!this.validateStringProperty(authorityPid, 50, true)) {
			// TODO 错误页面
			return "redirect:/error";
		} 
		Authority parentAuthority = this.authorityService.queryById(Long.parseLong(authorityPid));
		if(parentAuthority == null) {
			return "redirect:/error";
		}
		request.setAttribute("authorityPid", authorityPid);
		return "admin/sys/authority/add_sub_authority";
	}
	
	/**
	 * 进入系统权限编辑页面
	 * @param authorityId 权限Id
	 * @return sys/authority/edit_authority
	 */
	@GetMapping("/toEdit")
	public String gotoEditPage(@RequestParam(required = true, value = "authorityId") String authorityId) {
		// 后台数据验证
		if(!this.validateStringProperty(authorityId, 50, true)) {
			// TODO 错误页面
			return "redirect:/error";
		} 
		Authority editAuthority = this.authorityService.queryById(Long.parseLong(authorityId));
		if(editAuthority == null) {
			return "redirect:/error";
		}
		request.setAttribute("editAuthority", editAuthority);
		return "admin/sys/authority/edit_authority";
	}
	
	
	/**
	 * 加载菜单树表格数据
	 * @param pageNo 当前页码
	 * @param pageSize 每页记录数
	 * @return DataMesage
	 */
	@ResponseBody
	@PostMapping("/treeTable")
	public DataMessage selectTreeTable(
			@RequestParam(required = false, value = "pageNo") Integer pageNo,
			@RequestParam(required = false, value = "pageSize") Integer pageSize) {
		// 返回数据消息实体
		DataMessage dm = new DataMessage();
		List<Authority> resultList = new ArrayList<Authority>();
		PageHelper.startPage(getPageNo(pageNo), getPageSize(pageSize));
		List<Authority> authorityList = this.authorityService.queryList(null, null, null,
				getOrgId(), null, null, 0, null, 1, null, null, null, null, null,
				null, null, null);
		PageInfo<Authority> pageInfo = new PageInfo<Authority>(authorityList);
		for(Authority authority : authorityList) {
			this.recursionSubAuthority(resultList, authority);
		}
		dm.setResult(WyConstant.RESULT_CODE_SUCCESS);
		dm.setData(resultList);
		KKpager pager = new KKpager(getPageNo(pageNo), pageInfo.getPages() , pageInfo.getTotal());
		dm.setMessage(JSONObject.toJSON(pager).toString());
		return dm;
	}
	
	/**
	 * 验证权限是否存在
	 * @param authorityId 权限Id
	 * @param authorityName 权限名称
	 * @param authorityUrl 权限地址
	 * @param -validateType[authorityName | authorityUrl]
	 * @return DataMessage
	 */
	@ResponseBody
	@PostMapping("/validateIsAuthorityExist")
	public DataMessage validateIsAuthorityExist(
			@RequestParam(required = false, value = "authorityId") String authorityId,
			@RequestParam(required = false, value = "authorityName") String authorityName,
			@RequestParam(required = false, value = "authorityUrl") String authorityUrl,
			@RequestParam(required = true, value = "validateType") String validateType) throws ParseException {
		// 返回数据消息实体
		DataMessage dm = new DataMessage();
		// 后台数据验证
		if(!this.validateStringProperty(validateType, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("验证类型参数错误");
		} else if(!this.validateStringProperty(authorityId, 50, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限标识参数错误");
		} else if(!this.validateStringProperty(authorityName, 50, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限名称参数错误");
		} else if(!this.validateStringProperty(authorityUrl, 255, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限地址参数错误");
		} else {
			Long authId = null;
			if(authorityId != null && !"".equals(authorityId.trim())) {
				authId = Long.parseLong(authorityId);
			}
			dm.setResult(WyConstant.RESULT_CODE_SUCCESS);
			List<Authority> authList = this.authorityService.queryIsAuthorityExist(authId, authorityName, authorityUrl);
			if(authList == null || authList.size() == 0) {
				dm.setData("0");
			} else {
				dm.setData("1");
			}
		}
		return dm;
	}
	
	/**
	 * 添加系统根权限
	 * @param authorityName 权限名称
	 * @param authorityDesc 权限说明
	 * @param authorityKey 权限标识
	 * @param authorityUrl 权限地址
	 * @return DataMessage
	 */
	@ResponseBody
	@PostMapping("/addRoot")
	public DataMessage addRoot(
			@RequestParam(required = true, value = "authorityName") String authorityName,
			@RequestParam(required = false, value = "authorityDesc") String authorityDesc,
			@RequestParam(required = true, value = "authorityKey") String authorityKey,
			@RequestParam(required = true, value = "authorityUrl") String authorityUrl) {
		// 返回数据消息实体
		DataMessage dm = new DataMessage();
		// 后台数据验证
		if(!this.validateStringProperty(authorityName, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限名称参数错误");
		} else if(!this.validateStringProperty(authorityDesc, 255, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限说明参数错误");
		} else if(!this.validateStringProperty(authorityKey, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限标识参数错误");
		} else if(!this.validateStringProperty(authorityUrl, 500, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限地址参数错误");
		} else {
			boolean isExist = false;
			List<Authority> authList = this.authorityService.queryIsAuthorityExist(null, authorityName, null);
			if(authList != null && authList.size() > 0) {
				dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
				dm.setMessage("权限名称已经存在");
				isExist = true;
				return dm;
			} 
			authList = this.authorityService.queryIsAuthorityExist(null, null, authorityUrl);
			if(authList != null && authList.size() > 0) {
				dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
				dm.setMessage("权限地址已经存在");
				isExist = true;
				return dm;
			} 
			if(!isExist) {
				Long authorityId = this.authorityService.addRoot(getOrgId(), getOrgCode(), null, authorityName, authorityDesc, authorityKey, authorityUrl);
				dm.setResult(WyConstant.RESULT_CODE_SUCCESS);
				dm.setData(authorityId);
				dm.setMessage("权限添加成功");
			}
		}
		return dm;
	}
	
	/**
	 * 添加系统子权限
	 * @param authorityPid 父级Id
	 * @param authorityName 权限名称
	 * @param authorityDesc 权限说明
	 * @param authorityKey 权限标识
	 * @param authorityUrl 权限地址
	 * @return DataMessage
	 */
	@ResponseBody
	@PostMapping("/addSub")
	public DataMessage addSub(
			@RequestParam(required = true, value = "authorityPid") String authorityPid,
			@RequestParam(required = true, value = "authorityName") String authorityName,
			@RequestParam(required = false, value = "authorityDesc") String authorityDesc,
			@RequestParam(required = true, value = "authorityKey") String authorityKey,
			@RequestParam(required = true, value = "authorityUrl") String authorityUrl) {
		// 返回数据消息实体
		DataMessage dm = new DataMessage();
		// 后台数据验证
		if(!this.validateStringProperty(authorityPid, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限父级参数错误");
		} else if(!this.validateStringProperty(authorityName, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限名称参数错误");
		} else if(!this.validateStringProperty(authorityDesc, 255, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限说明参数错误");
		} else if(!this.validateStringProperty(authorityKey, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限标识参数错误");
		} else if(!this.validateStringProperty(authorityUrl, 500, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限地址参数错误");
		} else {
			boolean isExist = false;
			List<Authority> authList = this.authorityService.queryIsAuthorityExist(null, authorityName, null);
			if(authList != null && authList.size() > 0) {
				dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
				dm.setMessage("权限名称已经存在");
				isExist = true;
				return dm;
			} 
			authList = this.authorityService.queryIsAuthorityExist(null, null, authorityUrl);
			if(authList != null && authList.size() > 0) {
				dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
				dm.setMessage("权限地址已经存在");
				isExist = true;
				return dm;
			} 
			if(!isExist) {
				Long authorityId = this.authorityService.addSub(Long.parseLong(authorityPid), getOrgId(), getOrgCode(), null, authorityName, authorityDesc, authorityKey, authorityUrl);
				dm.setResult(WyConstant.RESULT_CODE_SUCCESS);
				dm.setData(authorityId);
				dm.setMessage("权限添加成功");
			}
		}
		return dm;
	}
	
	/**
	 * 编辑系统权限
	 * @param authorityId 权限Id
     * @param authorityName 权限名称
     * @param authorityKey 权限标识
	 * @param authorityDesc 权限说明
	 * @param authorityUrl 权限地址
	 * @return DataMessage
	 */
	@ResponseBody
	@PostMapping("/edit")
	public DataMessage edit(
			@RequestParam(required = true, value = "authorityId") String authorityId,
			@RequestParam(required = false, value = "authorityName") String authorityName,
			@RequestParam(required = false, value = "authorityKey") String authorityKey,
			@RequestParam(required = false, value = "authorityDesc") String authorityDesc,
			@RequestParam(required = true, value = "authorityUrl") String authorityUrl) {
		// 返回数据消息实体
		DataMessage dm = new DataMessage();
		// 后台数据验证
		if(!this.validateStringProperty(authorityId, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限Id参数错误");
		} else if(!this.validateStringProperty(authorityName, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限名称参数错误");
		} else if(!this.validateStringProperty(authorityKey, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限标识参数错误");
		} else if(!this.validateStringProperty(authorityDesc, 255, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限说明参数错误");
		} else if(!this.validateStringProperty(authorityUrl, 500, false)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限地址参数错误");
		} else {
			boolean isExist = false;
			List<Authority> authList = this.authorityService.queryIsAuthorityExist(Long.parseLong(authorityId), authorityName, null);
			if(authList != null && authList.size() > 0) {
				dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
				dm.setMessage("权限名称已经存在");
				isExist = true;
				return dm;
			} 
			authList = this.authorityService.queryIsAuthorityExist(Long.parseLong(authorityId), null, authorityUrl);
			if(authList != null && authList.size() > 0) {
				dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
				dm.setMessage("权限地址已经存在");
				isExist = true;
				return dm;
			} 
			if(!isExist) {
				this.authorityService.edit(Long.parseLong(authorityId), null, null, null, authorityName, authorityDesc, authorityKey, authorityUrl);
				dm.setResult(WyConstant.RESULT_CODE_SUCCESS);
				dm.setMessage("权限编辑成功");
			}
		}
		return dm;
	}
	
	/**
	 * 删除系统权限
	 * @param authorityId 权限Id
	 * @return DataMessage
	 */
	@ResponseBody
	@PostMapping("/delete")
	public DataMessage delete(@RequestParam(required = true, value = "authorityId") String authorityId) {
		// 返回数据消息实体
		DataMessage dm = new DataMessage();
		// 后台数据验证
		if(!this.validateStringProperty(authorityId, 50, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限Id参数错误");
		} else {
			this.authorityService.editIsDel(Long.parseLong(authorityId), 1);
			dm.setResult(WyConstant.RESULT_CODE_SUCCESS);
			dm.setMessage("权限删除成功");
		}
		return dm;
	}
	
	/**
	 * 批量删除系统权限
	 * @param authorityIds 权限Ids
	 * @return DataMessage
	 */
	@ResponseBody
	@PostMapping("/batchDelete")
	public DataMessage deleteBatch(@RequestParam(required = true, value = "authorityIds") String authorityIds) {
		// 返回数据消息实体
		DataMessage dm = new DataMessage();
		// 后台数据验证
		if(!this.validateStringProperty(authorityIds, 128, true)) {
			dm.setResult(WyConstant.RESULT_CODE_PARAMETER_ERROR);
			dm.setMessage("权限Ids参数错误");
		} else {
			String[] authorityIdsArr = authorityIds.split(",");
			for(String authorityId : authorityIdsArr) {
				this.authorityService.editIsDel(Long.parseLong(authorityId), 1);
			}
			dm.setResult(WyConstant.RESULT_CODE_SUCCESS);
			dm.setMessage("权限删除成功");
		}
		return dm;
	}
	
	/**
	 * 导出数据到Excel
	 * @return Excel File
	 * @throws Exception
	 */
	@PostMapping("/export")
    public ModelAndView exportExcel() throws Exception {
        Workbook wb = new HSSFWorkbook();
        Sheet sheet = wb.createSheet("系统权限信息");
        // 手动设置列宽。第一个参数表示要为第几列设；，第二个参数表示列的宽度，n为列高的像素数。
        sheet.setColumnWidth((short) 0, (short) (15.7 * 150));
        sheet.setColumnWidth((short) 1, (short) (25.7 * 150));
        sheet.setColumnWidth((short) 2, (short) (35.7 * 150));
        sheet.setColumnWidth((short) 3, (short) (35.7 * 150));
        sheet.setColumnWidth((short) 4, (short) (35.7 * 150));
        sheet.setColumnWidth((short) 5, (short) (35.7 * 150));
        sheet.setColumnWidth((short) 6, (short) (35.7 * 150));
        sheet.setColumnWidth((short) 7, (short) (35.7 * 150));
        sheet.setColumnWidth((short) 8, (short) (35.7 * 150));
        // 创建第一行
        Row row = sheet.createRow((short) 0);
        // 创建两种单元格格式
        CellStyle cs = wb.createCellStyle();
        CellStyle cs2 = wb.createCellStyle();
        
        // 创建两种字体
        Font f = wb.createFont();
        Font f2 = wb.createFont();
        
        // 创建第一种字体样式
        f.setFontHeightInPoints((short) 12);
        f.setColor(IndexedColors.BLACK.getIndex());
        f.setBoldweight(Font.BOLDWEIGHT_BOLD);
        // 创建第二种字体样式
        f2.setFontHeightInPoints((short) 11);
        f2.setColor(IndexedColors.BLACK.getIndex());
        f2.setBoldweight(Font.BOLDWEIGHT_NORMAL);
        
        // 设置第一种单元格的样式
        cs.setFont(f);
        cs.setBorderLeft(CellStyle.BORDER_THIN);
        cs.setBorderRight(CellStyle.BORDER_THIN);
        cs.setBorderTop(CellStyle.BORDER_THIN);
        cs.setBorderBottom(CellStyle.BORDER_THIN);
        cs.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        
        // 设置第二种单元格的样式
        cs2.setFont(f2);
        cs2.setBorderLeft(CellStyle.BORDER_THIN);
        cs2.setBorderRight(CellStyle.BORDER_THIN);
        cs2.setBorderTop(CellStyle.BORDER_THIN);
        cs2.setBorderBottom(CellStyle.BORDER_THIN);
        cs2.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        
        // 创建列（每行里的单元格）
        Cell cell = row.createCell(0);
        cell.setCellValue("序号");
        cell.setCellStyle(cs);
        
        cell = row.createCell(1);
        cell.setCellValue("权限编码");
        cell.setCellStyle(cs);
        
        cell = row.createCell(2);
        cell.setCellValue("权限级别");
        cell.setCellStyle(cs);
        
        cell = row.createCell(3);
        cell.setCellValue("权限名称");
        cell.setCellStyle(cs);
        
        cell = row.createCell(4);
        cell.setCellValue("权限标识");
        cell.setCellStyle(cs);
        
        cell = row.createCell(5);
        cell.setCellValue("权限地址");
        cell.setCellStyle(cs);
        
        cell = row.createCell(6);
        cell.setCellValue("权限说明");
        cell.setCellStyle(cs);
        
        PageHelper.orderBy("authority_code");
		List<Authority> authorityList = this.authorityService.queryList(null, null, getOrgType(), getOrgId(), null, null, 0, null, null, null, null, null,
				null, null, null, null, null);
    	for(int i = 0; i < authorityList.size(); i++) {
    		Authority authority = authorityList.get(i);
    		row = sheet.createRow(i + 1);
    		cell = row.createCell(0);
    		cell.setCellValue(i + 1);
    		cell.setCellStyle(cs2);
    		  
    		cell = row.createCell(1);
    		cell.setCellValue(authority.getAuthorityCode());
    		cell.setCellStyle(cs2);
    		
    		cell = row.createCell(2);
    		cell.setCellValue(authority.getAuthorityLevel());
    		cell.setCellStyle(cs2);
    		
    		  
    		cell = row.createCell(3);
    		cell.setCellValue(authority.getAuthorityName());
    		cell.setCellStyle(cs2);
    		
    		cell = row.createCell(4);
    		cell.setCellValue(authority.getAuthorityKey());
    		cell.setCellStyle(cs2);
    		
    		cell = row.createCell(5);
    		cell.setCellValue(authority.getAuthorityUrl());
    		cell.setCellStyle(cs2);
    	
    		  
    		cell = row.createCell(6);
    		cell.setCellValue((authority.getAuthorityDesc() == null || "".equals(authority.getAuthorityDesc().trim())) ? "—" : authority.getAuthorityDesc());
    		cell.setCellStyle(cs2);
    	}
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            wb.write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(("系统权限信息" + ".xls").getBytes(), "ISO-8859-1"));
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out);
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
        } catch (final IOException e) {
            throw e;
        } finally {
            if (bis != null)
                bis.close();
            if (bos != null)
                bos.close();
        }
        return null;
	}
	
	/**
	 * 递归添加权限子集
	 * @param resultList 结果List
	 * @param parentAuthority 父级权限
	 */
	private void recursionSubAuthority(List<Authority> resultList, Authority parentAuthority) {
		if(parentAuthority.getIsParent().intValue() == 1) {
			List<Authority> subList = this.authorityService.querySubList(parentAuthority.getAuthorityId());
			parentAuthority.setSubList(subList);
			resultList.add(parentAuthority);
			for(Authority sub : subList) {
				if(sub.getIsParent().intValue() == 1) {
					recursionSubAuthority(resultList, sub);
				}
			}
		} else {
			resultList.add(parentAuthority);
		}
	}
	
}